package javaMetaModel;

import java.util.Iterator;
import java.util.List;
import javaMetaModel.type.MetaType;
import javaMetaModel.visitor.IMetaModelVisitor;

public class Methode implements ICommentableEntity, IAnnotableEntity,
		IModifiableEntity, IVisibleEntity {

	private final MethodeSignature mSignature = new MethodeSignature();

	private MethodeBody mBody = new MethodeBody();

	public Annotations mAnnotations = new Annotations();

	private Comments mComments = new Comments();

	public Methode() {
		this("NewMethode");
	}

	public Methode(String aName) {
		this.mSignature.setName(aName);
		this.mSignature.setMethod(this);
	}

	public String getName() {
		return this.mSignature.getName();
	}

	public MethodeBody getBody() {
		return mBody;
	}

	public void setBody(MethodeBody aBody) {
		this.mBody = aBody;
	}

	public MethodeSignature getSignature() {
		return mSignature;
	}

	public void accept(IMetaModelVisitor aVisitor) {
		aVisitor.visitMethode(this);
	}

	public void addParam(Parameter aParam) {
		this.mSignature.addParam(aParam);
	}

	public void removeParam(Parameter aParam) {
		this.mSignature.removeParam(aParam);
	}

	@Override
	public void addAnnotation(String aString) {
		this.mAnnotations.addAnnotation(aString);
	}

	@Override
	public Annotations getAnnotations() {
		return this.mAnnotations;
	}

	@Override
	public void removeAnnotation(String aString) {
		this.mAnnotations.removeAnnotation(aString);
	}

	@Override
	public Comments getComments() {
		return this.mComments;
	}

	@Override
	public void addComment(String aComment) {
		this.mComments.addComment(aComment);
	}

	public void setReturnType(MetaType aReturnType) {
		this.mSignature.setReturnType(aReturnType);
	}

	public Modifier getModifier() {
		return this.getSignature().getModifier();
	}

	public void setPrivate() {
		this.getVisibility().setPrivate();
	}

	public void setProtected() {
		this.getVisibility().setProtected();
	}

	public void setPublic() {
		this.getVisibility().setPublic();
	}

	public boolean isAbstract() {
		return this.getModifier().isAbstract();
	}

	public void setAbstract(boolean mIsAbstract) {
		this.getModifier().setAbstract(mIsAbstract);
	}

	public boolean isFinal() {
		return this.getModifier().isFinal();
	}

	public void setFinal(boolean mIsFinal) {
		this.getModifier().setFinal(mIsFinal);
	}

	public boolean isStatic() {
		return this.getModifier().isStatic();
	}

	public void setStatic(boolean mIsStatic) {
		this.getModifier().setStatic(mIsStatic);
	}

	public Visibility getVisibility() {
		return this.getSignature().getVisibility();
	}

	public boolean isPrivate() {
		return this.getVisibility().isPrivate();
	}

	public boolean isProtected() {
		return this.getVisibility().isProtected();
	}

	public boolean isPublic() {
		return this.getVisibility().isPublic();
	}

	public MetaType getReturnType() {
		return this.mSignature.getReturnType();
	}

	public List<Parameter> getParams() {
		return this.mSignature.getParams();
	}

	/**
	 * Indique si la méthode possède un commentaire
	 */
	public boolean hasComment() {
		boolean hasComment = false;

		// Si le commentaire de la méthode est vide.
		if (!this.mComments.hasComment()) {

			// Vérification des commentaires des paramètres.
			Iterator<Parameter> paramIt = this.getParams().iterator();
			while (paramIt.hasNext()) {

				// Si un commentaire est présent
				if (paramIt.next().hasComment()) {

					// La méthode possède des commentaires
					hasComment = true;
					break;
				}
			}
		} else {
			hasComment = true;
		}

		return hasComment;
	}

	@Override
	public void setComment(String aComment) {
		this.mComments.setComment(aComment);
	}

}
